package ascloud.auth.web.ctrl;

import javax.annotation.Resource;

import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import ascloud.auth.client.CoreClient;
import ascloud.biz.domain.Filbert;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/res")
@SecurityRequirement(name = "security_auth")
public class ResourceController {

	@Resource
	private CoreClient coreClient;

	@Resource
	private CircuitBreakerFactory circuitBreakerFactory;

	@GetMapping("/check/{uid}")
	@PreAuthorize("@authz.check(#root, authentication, principal, #uid)")
	public String check(@PathVariable @P("uid") String uid) {
		return "check:" + uid;
	}

	@PreAuthorize("principal.claims['role'] != null and principal.claims['role'].contains('ROLE_ADMIN')")
	@GetMapping("/claim/admin")
	public String admin() {
		return "claim_admin";
	}

	@PreAuthorize("principal.claims['role'] != null and principal.claims['role'].contains('ROLE_STAFF')")
	@GetMapping("/claim/staff")
	public String staff() {
		return "claim_staff";
	}

	@PreAuthorize("principal.claims['role'] != null and principal.claims['role'].contains('ROLE_USER')")
	@GetMapping("/claim/user")
	public String user() {
		return "claim_user";
	}

	@PreAuthorize("hasRole('ADMIN')")
	@GetMapping("/role/admin")
	public String roleAdmin() {
		return "role_admin";
	}

	@PreAuthorize("hasRole('STAFF')")
	@GetMapping("/role/staff")
	public String roleStaff() {
		return "role_staff";
	}

	@PreAuthorize("hasRole('USER')")
	@GetMapping("/role/user")
	public String roleUser() {
		return "role_user";
	}

	@PreAuthorize("hasAuthority('SCOPE_email')")
	@GetMapping("/auth/scp/email")
	public String getEmail() {
		return "auth_scope_email";
	}

	@PreAuthorize("hasRole('USER')")
	@GetMapping("/core/hello")
	public String hello() {
		log.info("#####ResourceController.hello()####");
		return this.coreClient.hello();
	}

	@PreAuthorize("hasRole('USER')")
	@GetMapping("/core/filbert")
	public Filbert filbert() {
		log.info("#####ResourceController.filbert()####");
		return this.coreClient.filbert();
	}

	@PreAuthorize("hasRole('USER')")
	@GetMapping("/core/delay")
	public String delay() {
		log.info("#####ResourceController.delay()####");
		return this.circuitBreakerFactory.create("delay").run(() -> this.hello(), t -> {
			log.warn("delay call failed error", t);
			return "!!biz-core is down!!";
		});
	}

}
